﻿using System;
using System.Reflection;

using zijian666.Core.Abstractions;

namespace zijian666.Core;

/// <summary>
/// 用于操作属性的Get和Set
/// </summary>
public class PropertyHandler
{
    /// <summary>
    /// 初始化 <see cref="PropertyHandler"/>
    /// </summary>
    /// <param name="property">属性</param>
    private PropertyHandler(PropertyInfo property)
    {
        Property = property;
        PropertyType = property.PropertyType;
        Name = property.Name;
        Getter = property.CanRead ? property.GetValue : (MemberGetter<object>?)property.GetGetMethod(true)?.CreateDelegate(typeof(MemberGetter<object>));
        Setter = property.CanWrite ? property.SetValue : (MemberSetter<object>?)property.GetSetMethod(true)?.CreateDelegate(typeof(MemberSetter<object>));
    }

    /// <summary>
    /// 调用构造函数
    /// </summary>
    /// <param name="property">属性</param>
    /// <returns></returns>
    public static PropertyHandler Create(PropertyInfo property) => new(property);

    /// <summary>
    /// 属性类型
    /// </summary>
    public Type PropertyType { get; }
    /// <summary>
    /// 属性的Get方法委托
    /// </summary>
    protected MemberGetter<object>? Getter { get; }
    /// <summary>
    /// 属性的Set方法委托
    /// </summary>
    public MemberSetter<object>? Setter { get; }
    /// <summary>
    /// 属性
    /// </summary>
    public PropertyInfo Property { get; }
    /// <summary>
    /// 属性名称
    /// </summary>
    public string Name { get; }
    /// <summary>
    /// 获取属性的值
    /// </summary>
    public object? GetValue(object obj, IReflectCompiler? reflect)
    {
        var getter = reflect?.CompileGetter<object>(Property);
        return (getter ?? Getter)?.Invoke(obj);
    }
    /// <summary>
    /// 设置属性的值
    /// </summary>
    public void SetValue(object obj, object? value, IReflectCompiler? reflect)
    {
        var setter = reflect?.CompileSetter<object>(Property);
#pragma warning disable CS8604 
        (setter ?? Setter)?.Invoke(obj, value);
#pragma warning restore CS8604 
    }
}
